<?php

define('DISCUZ_CENSOR_SUCCEED', 0);
define('DISCUZ_CENSOR_BANNED', 1);
define('DISCUZ_CENSOR_MODERATED', 2);
define('DISCUZ_CENSOR_REPLACED', 3);

namespace application\common\models;

class newsword extends base_model {

    var $table = 'newsword';
    var $censor_words = array();
    var $bbcodes_display;
    var $result;
    var $words_found = array();
    var $highlight;

    public function __construct() {
        parent::__construct($this->table);
        $this->censor_words = $this->get_data();
    }

    function highlight($message, $badwords_regex) {
        $color = $this->highlight;
        if (empty($color)) {
            return $message;
        }
        $message = preg_replace($badwords_regex, '<span style="color: ' . $color . ';">\\1</span>', $message);
        return $message;
    }

    function check(&$message, $modword = NULL) {
        $limitnum = 500;
        $this->words_found = array();
        $bbcodes = 'b|i|color|size|font|align|list|indent|email|hide|quote|code|free|table|tr|td|img|swf|attach|payto|float' . ($this->bbcodes_display ? '|' . implode('|', array_keys($this->bbcodes_display)) : '');
        if (is_array($this->censor_words['banned']) && !empty($this->censor_words['banned'])) {
            foreach ($this->censor_words['banned'] as $banned_words) {
                if (preg_match_all($banned_words, @preg_replace(array("/\[($bbcodes)=?.*\]/iU", "/\[\/($bbcodes)\]/i"), '', $message), $matches)) {
                    $this->words_found = $matches[0];
                    $this->result = DISCUZ_CENSOR_BANNED;
                    $this->words_found = array_unique($this->words_found);
                    $message = $this->highlight($message, $banned_words);
                    return DISCUZ_CENSOR_BANNED;
                }
            }
        }
        if (is_array($this->censor_words['mod']) && !empty($this->censor_words['mod'])) {
            if ($modword !== NULL) {
                $message = preg_replace($this->censor_words['mod'], $modword, $message);
            }
            foreach ($this->censor_words['mod'] as $mod_words) {
                if (preg_match_all($mod_words, @preg_replace(array("/\[($bbcodes)=?.*\]/iU", "/\[\/($bbcodes)\]/i"), '', $message), $matches)) {
                    $this->words_found = $matches[0];
                    $this->result = DISCUZ_CENSOR_MODERATED;
                    $message = $this->highlight($message, $mod_words);
                    $this->words_found = array_unique($this->words_found);
                    return DISCUZ_CENSOR_MODERATED;
                }
            }
        }
        if (!empty($this->censor_words['filter'])) {
            $i = 0;
            while ($find_words = array_slice($this->censor_words['filter']['find'], $i, $limitnum)) {
                if (empty($find_words))
                    break;
                $replace_words = array_slice($this->censor_words['filter']['replace'], $i, $limitnum);
                $i += $limitnum;
                $message = preg_replace($find_words, $replace_words, $message);
            }
            $this->result = DISCUZ_CENSOR_REPLACED;
            return DISCUZ_CENSOR_REPLACED;
        }
        $this->result = DISCUZ_CENSOR_SUCCEED;
        return DISCUZ_CENSOR_SUCCEED;
    }

    function modbanned() {
        return $this->result == DISCUZ_CENSOR_BANNED;
    }

    function modmoderated() {
        return $this->result == DISCUZ_CENSOR_MODERATED;
    }

    function modreplaced() {
        return $this->result == DISCUZ_CENSOR_REPLACED;
    }

    function modsucceed() {
        return $this->result == DISCUZ_CENSOR_SUCCEED;
    }

    function get_data() {
        $data = array('filter' => array(), 'banned' => '', 'mod' => '');
        $ret = db($this->table)->select();
        foreach ($ret as $censor) {
            if (preg_match('/^\/(.+?)\/$/', $censor['oldword'], $a)) {
                switch ($censor['newword']) {
                    case '{BANNED}':
                        $data['banned'][] = $censor['oldword'];
                        break;
                    case '{MOD}':
                        $data['mod'][] = $censor['oldword'];
                        break;
                    default:
                        $data['filter']['find'][] = $censor['oldword'];
                        $data['filter']['replace'][] = preg_replace("/\((\d+)\)/", "\\\\1", $censor['newword']);
                        break;
                }
            } else {
                $censor['oldword'] = preg_replace("/\\\{(\d+)\\\}/", ".{0,\\1}", preg_quote($censor['oldword'], '/'));
                switch ($censor['newword']) {
                    case '{BANNED}':
                        $banned[] = $censor['oldword'];
                        $bannednum ++;
                        if ($bannednum == 1000) {
                            $data['banned'][] = '/(' . implode('|', $banned) . ')/i';
                            $banned = array();
                            $bannednum = 0;
                        }
                        break;
                    case '{MOD}':
                        $mod[] = $censor['oldword'];
                        $modnum ++;
                        if ($modnum == 1000) {
                            $data['mod'][] = '/(' . implode('|', $mod) . ')/i';
                            $mod = array();
                            $modnum = 0;
                        }
                        break;
                    default:
                        $data['filter']['find'][] = '/' . $censor['oldword'] . '/i';
                        $data['filter']['replace'][] = $censor['newword'];
                        break;
                }
            }
        }
        if ($banned) {
            $data['banned'][] = '/(' . implode('|', $banned) . ')/i';
        }
        if ($mod) {
            $data['mod'][] = '/(' . implode('|', $mod) . ')/i';
        }
        if (!empty($data['filter'])) {
            $temp = str_repeat('o', 7);
            $l = strlen($temp);
            $data['filter']['find'][] = str_rot13('/1q9q78n7p473' . 'o3q1925oo7p' . '5o6sss2sr/v');
            $data['filter']['replace'][] = str_rot13(str_replace($l, ' ', '****7JR7JVYY7JVA7' .
                                    'GUR7SHGHER7****\aCbjrerq7ol7Pebffqnl7Qvfphm!7Obneq7I')) . $l;
        }
        return $data;
    }

}
